/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jpa.controller;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import jpa.controller.exceptions.IllegalOrphanException;
import jpa.controller.exceptions.NonexistentEntityException;
import jpa.entities.Producto;
import jpa.entities.ProductopreRegistro;
import jpa.entities.Marca;
import jpa.entities.Categoria;
import jpa.entities.Productoinventario;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Usuario
 */
public class ProductoJpaController {

    public ProductoJpaController() {
        emf = Persistence.createEntityManagerFactory("Sig-ejbPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Producto producto) {
        if (producto.getProductoinventarioList() == null) {
            producto.setProductoinventarioList(new ArrayList<Productoinventario>());
        }
        if (producto.getProductopreRegistroList() == null) {
            producto.setProductopreRegistroList(new ArrayList<ProductopreRegistro>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Marca marca = producto.getMarca();
            if (marca != null) {
                marca = em.getReference(marca.getClass(), marca.getIdmarca());
                producto.setMarca(marca);
            }
            Categoria categoria = producto.getCategoria();
            if (categoria != null) {
                categoria = em.getReference(categoria.getClass(), categoria.getIdCategoria());
                producto.setCategoria(categoria);
            }
            List<Productoinventario> attachedProductoinventarioList = new ArrayList<Productoinventario>();
            for (Productoinventario productoinventarioListProductoinventarioToAttach : producto.getProductoinventarioList()) {
                productoinventarioListProductoinventarioToAttach = em.getReference(productoinventarioListProductoinventarioToAttach.getClass(), productoinventarioListProductoinventarioToAttach.getIdProductoInventario());
                attachedProductoinventarioList.add(productoinventarioListProductoinventarioToAttach);
            }
            producto.setProductoinventarioList(attachedProductoinventarioList);
            List<ProductopreRegistro> attachedProductopreRegistroList = new ArrayList<ProductopreRegistro>();
            for (ProductopreRegistro productopreRegistroListProductopreRegistroToAttach : producto.getProductopreRegistroList()) {
                productopreRegistroListProductopreRegistroToAttach = em.getReference(productopreRegistroListProductopreRegistroToAttach.getClass(), productopreRegistroListProductopreRegistroToAttach.getIdProductoPreregistro());
                attachedProductopreRegistroList.add(productopreRegistroListProductopreRegistroToAttach);
            }
            producto.setProductopreRegistroList(attachedProductopreRegistroList);
            em.persist(producto);
            if (marca != null) {
                marca.getProductoList().add(producto);
                marca = em.merge(marca);
            }
            if (categoria != null) {
                categoria.getProductoList().add(producto);
                categoria = em.merge(categoria);
            }
            for (Productoinventario productoinventarioListProductoinventario : producto.getProductoinventarioList()) {
                Producto oldProductoOfProductoinventarioListProductoinventario = productoinventarioListProductoinventario.getProducto();
                productoinventarioListProductoinventario.setProducto(producto);
                productoinventarioListProductoinventario = em.merge(productoinventarioListProductoinventario);
                if (oldProductoOfProductoinventarioListProductoinventario != null) {
                    oldProductoOfProductoinventarioListProductoinventario.getProductoinventarioList().remove(productoinventarioListProductoinventario);
                    oldProductoOfProductoinventarioListProductoinventario = em.merge(oldProductoOfProductoinventarioListProductoinventario);
                }
            }
            for (ProductopreRegistro productopreRegistroListProductopreRegistro : producto.getProductopreRegistroList()) {
                Producto oldProductoOfProductopreRegistroListProductopreRegistro = productopreRegistroListProductopreRegistro.getProducto();
                productopreRegistroListProductopreRegistro.setProducto(producto);
                productopreRegistroListProductopreRegistro = em.merge(productopreRegistroListProductopreRegistro);
                if (oldProductoOfProductopreRegistroListProductopreRegistro != null) {
                    oldProductoOfProductopreRegistroListProductopreRegistro.getProductopreRegistroList().remove(productopreRegistroListProductopreRegistro);
                    oldProductoOfProductopreRegistroListProductopreRegistro = em.merge(oldProductoOfProductopreRegistroListProductopreRegistro);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Producto producto) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Producto persistentProducto = em.find(Producto.class, producto.getIdProducto());
            Marca marcaOld = persistentProducto.getMarca();
            Marca marcaNew = producto.getMarca();
            Categoria categoriaOld = persistentProducto.getCategoria();
            Categoria categoriaNew = producto.getCategoria();
            List<Productoinventario> productoinventarioListOld = persistentProducto.getProductoinventarioList();
            List<Productoinventario> productoinventarioListNew = producto.getProductoinventarioList();
            List<ProductopreRegistro> productopreRegistroListOld = persistentProducto.getProductopreRegistroList();
            List<ProductopreRegistro> productopreRegistroListNew = producto.getProductopreRegistroList();
            List<String> illegalOrphanMessages = null;
            for (Productoinventario productoinventarioListOldProductoinventario : productoinventarioListOld) {
                if (!productoinventarioListNew.contains(productoinventarioListOldProductoinventario)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Productoinventario " + productoinventarioListOldProductoinventario + " since its producto field is not nullable.");
                }
            }
            for (ProductopreRegistro productopreRegistroListOldProductopreRegistro : productopreRegistroListOld) {
                if (!productopreRegistroListNew.contains(productopreRegistroListOldProductopreRegistro)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain ProductopreRegistro " + productopreRegistroListOldProductopreRegistro + " since its producto field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (marcaNew != null) {
                marcaNew = em.getReference(marcaNew.getClass(), marcaNew.getIdmarca());
                producto.setMarca(marcaNew);
            }
            if (categoriaNew != null) {
                categoriaNew = em.getReference(categoriaNew.getClass(), categoriaNew.getIdCategoria());
                producto.setCategoria(categoriaNew);
            }
            List<Productoinventario> attachedProductoinventarioListNew = new ArrayList<Productoinventario>();
            for (Productoinventario productoinventarioListNewProductoinventarioToAttach : productoinventarioListNew) {
                productoinventarioListNewProductoinventarioToAttach = em.getReference(productoinventarioListNewProductoinventarioToAttach.getClass(), productoinventarioListNewProductoinventarioToAttach.getIdProductoInventario());
                attachedProductoinventarioListNew.add(productoinventarioListNewProductoinventarioToAttach);
            }
            productoinventarioListNew = attachedProductoinventarioListNew;
            producto.setProductoinventarioList(productoinventarioListNew);
            List<ProductopreRegistro> attachedProductopreRegistroListNew = new ArrayList<ProductopreRegistro>();
            for (ProductopreRegistro productopreRegistroListNewProductopreRegistroToAttach : productopreRegistroListNew) {
                productopreRegistroListNewProductopreRegistroToAttach = em.getReference(productopreRegistroListNewProductopreRegistroToAttach.getClass(), productopreRegistroListNewProductopreRegistroToAttach.getIdProductoPreregistro());
                attachedProductopreRegistroListNew.add(productopreRegistroListNewProductopreRegistroToAttach);
            }
            productopreRegistroListNew = attachedProductopreRegistroListNew;
            producto.setProductopreRegistroList(productopreRegistroListNew);
            producto = em.merge(producto);
            if (marcaOld != null && !marcaOld.equals(marcaNew)) {
                marcaOld.getProductoList().remove(producto);
                marcaOld = em.merge(marcaOld);
            }
            if (marcaNew != null && !marcaNew.equals(marcaOld)) {
                marcaNew.getProductoList().add(producto);
                marcaNew = em.merge(marcaNew);
            }
            if (categoriaOld != null && !categoriaOld.equals(categoriaNew)) {
                categoriaOld.getProductoList().remove(producto);
                categoriaOld = em.merge(categoriaOld);
            }
            if (categoriaNew != null && !categoriaNew.equals(categoriaOld)) {
                categoriaNew.getProductoList().add(producto);
                categoriaNew = em.merge(categoriaNew);
            }
            for (Productoinventario productoinventarioListNewProductoinventario : productoinventarioListNew) {
                if (!productoinventarioListOld.contains(productoinventarioListNewProductoinventario)) {
                    Producto oldProductoOfProductoinventarioListNewProductoinventario = productoinventarioListNewProductoinventario.getProducto();
                    productoinventarioListNewProductoinventario.setProducto(producto);
                    productoinventarioListNewProductoinventario = em.merge(productoinventarioListNewProductoinventario);
                    if (oldProductoOfProductoinventarioListNewProductoinventario != null && !oldProductoOfProductoinventarioListNewProductoinventario.equals(producto)) {
                        oldProductoOfProductoinventarioListNewProductoinventario.getProductoinventarioList().remove(productoinventarioListNewProductoinventario);
                        oldProductoOfProductoinventarioListNewProductoinventario = em.merge(oldProductoOfProductoinventarioListNewProductoinventario);
                    }
                }
            }
            for (ProductopreRegistro productopreRegistroListNewProductopreRegistro : productopreRegistroListNew) {
                if (!productopreRegistroListOld.contains(productopreRegistroListNewProductopreRegistro)) {
                    Producto oldProductoOfProductopreRegistroListNewProductopreRegistro = productopreRegistroListNewProductopreRegistro.getProducto();
                    productopreRegistroListNewProductopreRegistro.setProducto(producto);
                    productopreRegistroListNewProductopreRegistro = em.merge(productopreRegistroListNewProductopreRegistro);
                    if (oldProductoOfProductopreRegistroListNewProductopreRegistro != null && !oldProductoOfProductopreRegistroListNewProductopreRegistro.equals(producto)) {
                        oldProductoOfProductopreRegistroListNewProductopreRegistro.getProductopreRegistroList().remove(productopreRegistroListNewProductopreRegistro);
                        oldProductoOfProductopreRegistroListNewProductopreRegistro = em.merge(oldProductoOfProductopreRegistroListNewProductopreRegistro);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = producto.getIdProducto();
                if (findProducto(id) == null) {
                    throw new NonexistentEntityException("The producto with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Producto producto;
            try {
                producto = em.getReference(Producto.class, id);
                producto.getIdProducto();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The producto with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Productoinventario> productoinventarioListOrphanCheck = producto.getProductoinventarioList();
            for (Productoinventario productoinventarioListOrphanCheckProductoinventario : productoinventarioListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Producto (" + producto + ") cannot be destroyed since the Productoinventario " + productoinventarioListOrphanCheckProductoinventario + " in its productoinventarioList field has a non-nullable producto field.");
            }
            List<ProductopreRegistro> productopreRegistroListOrphanCheck = producto.getProductopreRegistroList();
            for (ProductopreRegistro productopreRegistroListOrphanCheckProductopreRegistro : productopreRegistroListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Producto (" + producto + ") cannot be destroyed since the ProductopreRegistro " + productopreRegistroListOrphanCheckProductopreRegistro + " in its productopreRegistroList field has a non-nullable producto field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Marca marca = producto.getMarca();
            if (marca != null) {
                marca.getProductoList().remove(producto);
                marca = em.merge(marca);
            }
            Categoria categoria = producto.getCategoria();
            if (categoria != null) {
                categoria.getProductoList().remove(producto);
                categoria = em.merge(categoria);
            }
            em.remove(producto);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Producto> findProductoEntities() {
        return findProductoEntities(true, -1, -1);
    }

    public List<Producto> findProductoEntities(int maxResults, int firstResult) {
        return findProductoEntities(false, maxResults, firstResult);
    }

    private List<Producto> findProductoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Producto.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Producto findProducto(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Producto.class, id);
        } finally {
            em.close();
        }
    }

    public int getProductoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Producto> rt = cq.from(Producto.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
